{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Dynamic Nelson-Siegel Model\n",
    "Xutao Chen\n",
    "\n",
    "DNS (Dynamic Nelson-Siegel) Model is a classical parameteric term-structure model for fixed income. This Notebook will show how to constrcut DNS and tune its parameter. Then I will use it to do prediction and compare its result with random walk."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/statsmodels/compat/pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.\n",
      "  from pandas.core import datetools\n"
     ]
    }
   ],
   "source": [
    "#Import all necessary package\n",
    "from scipy.optimize import least_squares, leastsq\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import statsmodels.api as sm\n",
    "from statsmodels.tsa.arima_model import ARMA\n",
    "from datetime import timedelta\n",
    "import holidays\n",
    "import warnings; warnings.simplefilter('ignore')\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>3 MO</th>\n",
       "      <th>6 MO</th>\n",
       "      <th>1 YR</th>\n",
       "      <th>2 YR</th>\n",
       "      <th>3 YR</th>\n",
       "      <th>5 YR</th>\n",
       "      <th>7 YR</th>\n",
       "      <th>10 YR</th>\n",
       "      <th>20 YR</th>\n",
       "      <th>30 YR</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2016-12-23</th>\n",
       "      <td>0.52</td>\n",
       "      <td>0.65</td>\n",
       "      <td>0.87</td>\n",
       "      <td>1.22</td>\n",
       "      <td>1.54</td>\n",
       "      <td>2.04</td>\n",
       "      <td>2.35</td>\n",
       "      <td>2.55</td>\n",
       "      <td>2.86</td>\n",
       "      <td>3.12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-27</th>\n",
       "      <td>0.51</td>\n",
       "      <td>0.66</td>\n",
       "      <td>0.89</td>\n",
       "      <td>1.28</td>\n",
       "      <td>1.58</td>\n",
       "      <td>2.07</td>\n",
       "      <td>2.37</td>\n",
       "      <td>2.57</td>\n",
       "      <td>2.88</td>\n",
       "      <td>3.14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-28</th>\n",
       "      <td>0.53</td>\n",
       "      <td>0.62</td>\n",
       "      <td>0.90</td>\n",
       "      <td>1.26</td>\n",
       "      <td>1.55</td>\n",
       "      <td>2.02</td>\n",
       "      <td>2.32</td>\n",
       "      <td>2.51</td>\n",
       "      <td>2.83</td>\n",
       "      <td>3.09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-29</th>\n",
       "      <td>0.47</td>\n",
       "      <td>0.62</td>\n",
       "      <td>0.85</td>\n",
       "      <td>1.22</td>\n",
       "      <td>1.49</td>\n",
       "      <td>1.96</td>\n",
       "      <td>2.30</td>\n",
       "      <td>2.49</td>\n",
       "      <td>2.82</td>\n",
       "      <td>3.08</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-30</th>\n",
       "      <td>0.51</td>\n",
       "      <td>0.62</td>\n",
       "      <td>0.85</td>\n",
       "      <td>1.20</td>\n",
       "      <td>1.47</td>\n",
       "      <td>1.93</td>\n",
       "      <td>2.25</td>\n",
       "      <td>2.45</td>\n",
       "      <td>2.79</td>\n",
       "      <td>3.06</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            3 MO  6 MO  1 YR  2 YR  3 YR  5 YR  7 YR  10 YR  20 YR  30 YR\n",
       "Date                                                                     \n",
       "2016-12-23  0.52  0.65  0.87  1.22  1.54  2.04  2.35   2.55   2.86   3.12\n",
       "2016-12-27  0.51  0.66  0.89  1.28  1.58  2.07  2.37   2.57   2.88   3.14\n",
       "2016-12-28  0.53  0.62  0.90  1.26  1.55  2.02  2.32   2.51   2.83   3.09\n",
       "2016-12-29  0.47  0.62  0.85  1.22  1.49  1.96  2.30   2.49   2.82   3.08\n",
       "2016-12-30  0.51  0.62  0.85  1.20  1.47  1.93  2.25   2.45   2.79   3.06"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Load the data -- Constant maturity yield in US market\n",
    "df = pd.read_csv(\"CMT_Rates.csv\")\n",
    "df.set_index(['Date'],inplace=True)\n",
    "df.index = pd.to_datetime(df.index,yearfirst=True)\n",
    "df.dropna(inplace=True)\n",
    "df.drop([\"1 MO\"],axis=1,inplace=True)\n",
    "term = [3/12.,6/12.,1,2,3,5,7,10,20,30]\n",
    "sample = df.loc[\"2012-01-01\":\"2016-12-31\"]\n",
    "sample.tail(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model Construction\n",
    "Implement DNS Model and find the optimal lamda"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Nelson-Siegel Model (DNS)\n",
    "class Model:\n",
    "    def __init__(self,lamda,data,term):\n",
    "        self.lamda = lamda\n",
    "        self.data = data\n",
    "        self.term = term\n",
    "        self.loadings = self.cal_loading()\n",
    "        self.betas = []\n",
    "    \n",
    "    #Calculate the loading matrix for a specific lamda\n",
    "    def cal_loading(self):\n",
    "        loading1 = np.vstack([1]*len(self.term))\n",
    "        loading2 = np.vstack((1-np.exp(-self.lamda*tau)) / (self.lamda*tau) for tau in self.term)\n",
    "        loading3 = np.vstack((1-np.exp(-self.lamda*tau)) / (self.lamda*tau) - np.exp(-self.lamda*tau) for tau in self.term)\n",
    "        loadings = np.hstack([loading1,loading2,loading3])\n",
    "        return loadings\n",
    "    \n",
    "    # Calculate the residuals in time series and cross-sectional for a specific lamda\n",
    "    def residuals(self,lamda):\n",
    "        self.update_params(lamda)\n",
    "        allresiduals = np.empty([len(self.term)])\n",
    "        # Time-series loop\n",
    "        for index in self.data.index:\n",
    "            y = self.data.loc[index].values\n",
    "            model = sm.OLS(y,self.loadings)\n",
    "            results = model.fit()\n",
    "            y_hat = results.predict(self.loadings)\n",
    "            betas = results.params\n",
    "            self.betas.append(betas)\n",
    "            # cross-sectional residuals\n",
    "            residuals = y - y_hat\n",
    "            allresiduals = np.concatenate([allresiduals,residuals])\n",
    "        return allresiduals\n",
    "    \n",
    "    # Fit the model to find the optimal lamda\n",
    "    def fit(self,lamda0,solver='lm'):\n",
    "        return least_squares(self.residuals,lamda0,method=solver)\n",
    "    \n",
    "    # Update the parameters -- lamda and loading matrix\n",
    "    def update_params(self,lamda):\n",
    "        self.lamda = lamda\n",
    "        self.betas = []\n",
    "        self.loadings = self.cal_loading()\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The optimal lamda is 0.45\n"
     ]
    }
   ],
   "source": [
    "# Initial lamda\n",
    "lamda = 0.6\n",
    "model = Model(lamda,sample,term)\n",
    "fo = model.fit(lamda)\n",
    "print(\"The optimal lamda is %0.2f\"%fo.x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model Prediction\n",
    "Use DNS model to forecast and compare the results with those predicted by random walk model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 1 Find the 20 days with largest RMSE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>RMSE</th>\n",
       "      <th>beta1</th>\n",
       "      <th>beta2</th>\n",
       "      <th>beta3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2016-12-23</th>\n",
       "      <td>0.039259</td>\n",
       "      <td>3.319071</td>\n",
       "      <td>-2.938875</td>\n",
       "      <td>-0.522285</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-27</th>\n",
       "      <td>0.036175</td>\n",
       "      <td>3.319887</td>\n",
       "      <td>-2.944913</td>\n",
       "      <td>-0.382847</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-28</th>\n",
       "      <td>0.037766</td>\n",
       "      <td>3.264882</td>\n",
       "      <td>-2.879944</td>\n",
       "      <td>-0.433325</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-29</th>\n",
       "      <td>0.037340</td>\n",
       "      <td>3.272291</td>\n",
       "      <td>-2.915716</td>\n",
       "      <td>-0.559228</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-12-30</th>\n",
       "      <td>0.036516</td>\n",
       "      <td>3.253188</td>\n",
       "      <td>-2.860177</td>\n",
       "      <td>-0.699686</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                RMSE     beta1     beta2     beta3\n",
       "Date                                              \n",
       "2016-12-23  0.039259  3.319071 -2.938875 -0.522285\n",
       "2016-12-27  0.036175  3.319887 -2.944913 -0.382847\n",
       "2016-12-28  0.037766  3.264882 -2.879944 -0.433325\n",
       "2016-12-29  0.037340  3.272291 -2.915716 -0.559228\n",
       "2016-12-30  0.036516  3.253188 -2.860177 -0.699686"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Construct a dataframe of RMSEs and betas\n",
    "residuals = model.residuals(model.lamda)\n",
    "residuals = residuals.reshape(-1,len(term))\n",
    "residuals = residuals[1:,:]\n",
    "RMSE = np.sqrt(np.mean(np.power(residuals,2),axis=1))\n",
    "RMSE = RMSE.reshape(-1,1)\n",
    "betas = np.vstack(model.betas)\n",
    "results_df = pd.DataFrame(np.hstack([RMSE,betas]),sample.index,columns=[\"RMSE\",\"beta1\",\"beta2\",\"beta3\"])\n",
    "results_df.tail(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Followings are the 20 days with largest RMSE\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2013-12-31', '2013-12-24', '2013-12-27', '2014-01-02',\n",
       "               '2013-12-30', '2014-01-03', '2013-12-23', '2013-12-26',\n",
       "               '2013-12-19', '2014-04-21', '2014-04-24', '2013-12-20',\n",
       "               '2014-01-08', '2014-04-17', '2014-01-06', '2014-04-22',\n",
       "               '2014-04-28', '2014-04-25', '2014-04-23', '2014-04-03'],\n",
       "              dtype='datetime64[ns]', name='Date', freq=None)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results_df_sorted = results_df.sort_values(by=\"RMSE\",ascending=False)\n",
    "index_best20 = results_df_sorted.iloc[:20].index\n",
    "print(\"Followings are the 20 days with largest RMSE\")\n",
    "index_best20"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 2 Use DNS Model to predict\n",
    "1. Use the 6 month data prior to each of those 20 days as sample; \n",
    "2. Do AR fitting and prediction for betas\n",
    "3. Calculate the predicted CMT rates by plugging predicted betas into DNS model\n",
    "4. Get the summary of prediction results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define a function to find the next business day\n",
    "HOLIDAYS_US = holidays.US()\n",
    "def next_business_day(startDate,gap):\n",
    "    next_day = startDate+timedelta(days=gap)\n",
    "    while next_day.weekday() in holidays.WEEKEND or next_day in HOLIDAYS_US:\n",
    "        next_day += timedelta(days=1)\n",
    "    return next_day\n",
    "# Define a function to compute half-lives\n",
    "def get_halflife(y):\n",
    "    y_lag = y.shift(1)\n",
    "    y_ret = y - y_lag\n",
    "    y_lag = y_lag[1:]\n",
    "    y_ret = y_ret[1:]\n",
    "    y_lag2 = sm.add_constant(y_lag)\n",
    "\n",
    "    model = sm.OLS(y_ret.values,y_lag2.values)\n",
    "    res = model.fit()\n",
    "\n",
    "    halflife = round(-np.log(2) / res.params[1],0)\n",
    "    return halflife\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>beta1</th>\n",
       "      <th>beta2</th>\n",
       "      <th>beta3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-12-31</th>\n",
       "      <td>8.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-12-24</th>\n",
       "      <td>10.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-12-27</th>\n",
       "      <td>9.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-02</th>\n",
       "      <td>11.0</td>\n",
       "      <td>11.0</td>\n",
       "      <td>14.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-12-30</th>\n",
       "      <td>8.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            beta1  beta2  beta3\n",
       "Date                           \n",
       "2013-12-31    8.0    8.0   16.0\n",
       "2013-12-24   10.0    9.0   16.0\n",
       "2013-12-27    9.0    9.0   16.0\n",
       "2014-01-02   11.0   11.0   14.0\n",
       "2013-12-30    8.0    8.0   16.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Do 3 predictions for t+5d, t+10d, t+1M\n",
    "loadings = model.loadings\n",
    "maturity = sample.columns.values\n",
    "length_sample = 182\n",
    "length_predict = [5,10,20]\n",
    "results_5d = []\n",
    "results_10d = []\n",
    "results_1M = []\n",
    "\n",
    "hls_beta1 = []\n",
    "hls_beta2 = []\n",
    "hls_beta3 = []\n",
    "\n",
    "series_num = 1\n",
    "for index in index_best20:\n",
    "    # For each of date in best20, select data 6 month prior to that date as sample \n",
    "    # to fit AR models for betas\n",
    "    endDate_sample = index\n",
    "    startDate_sample = next_business_day(endDate_sample,-length_sample)\n",
    "    sample_6m = results_df.loc[startDate_sample:endDate_sample,[\"beta1\",\"beta2\",\"beta3\"]]\n",
    "    \n",
    "    # Calculate the HL of betas in sample\n",
    "    hl_beta1 = get_halflife(sample_6m[\"beta1\"])\n",
    "    hl_beta2 = get_halflife(sample_6m[\"beta2\"])\n",
    "    hl_beta3 = get_halflife(sample_6m[\"beta3\"])\n",
    "    hls_beta1.append(hl_beta1)\n",
    "    hls_beta2.append(hl_beta2)\n",
    "    hls_beta3.append(hl_beta3)\n",
    "    \n",
    "    # Calculate the index for prediction\n",
    "    start_index = len(sample_6m)\n",
    "    end_index = start_index + 20\n",
    "    # Fit the AR models for betas and predict\n",
    "    AR_beta1 = ARMA(sample_6m[\"beta1\"].values,(1,0))\n",
    "    result1 = AR_beta1.fit()\n",
    "    beta1_hat = result1.predict(start=start_index,end=end_index,dynamic=True)\n",
    "\n",
    "    AR_beta2 = ARMA(sample_6m[\"beta2\"].values,(1,0))\n",
    "    result2 = AR_beta2.fit()\n",
    "    beta2_hat = result2.predict(start=start_index,end=end_index,dynamic=True)\n",
    "\n",
    "    AR_beta3 = ARMA(sample_6m[\"beta3\"].values,(1,0))\n",
    "    result3 = AR_beta3.fit()\n",
    "    beta3_hat = result3.predict(start=start_index,end=end_index,dynamic=True)\n",
    "\n",
    "    predictions = []\n",
    "    for length in length_predict:\n",
    "        # Forecast the CMT rate based on loadings and predicted betas\n",
    "        CMT_hat = beta1_hat[length-1]*loadings[:,0]+beta2_hat[length-1]*loadings[:,1]+beta3_hat[length-1]*loadings[:,2]\n",
    "\n",
    "        # Slice the corresponding observation, and calculate the residuals\n",
    "        CMT = sample.loc[next_business_day(endDate_sample,length)].values\n",
    "        residuals = CMT - CMT_hat\n",
    "\n",
    "        series = np.array([series_num]*len(CMT))\n",
    "\n",
    "        data = np.hstack([maturity.reshape(-1,1),series.reshape(-1,1),CMT_hat.reshape(-1,1),residuals.reshape(-1,1)])\n",
    "\n",
    "        df_predict = pd.DataFrame(data,columns=[\"Maturity\",\"Series\",\"prediction\",\"residual\"])\n",
    "\n",
    "        predictions.append(df_predict)\n",
    "    \n",
    "    results_5d.append(predictions[0])\n",
    "    results_10d.append(predictions[1])\n",
    "    results_1M.append(predictions[2])\n",
    "    \n",
    "    series_num += 1\n",
    "\n",
    "hl_df = pd.DataFrame({\"beta1\":hls_beta1,\"beta2\":hls_beta2,\"beta3\":hls_beta3},index=index_best20)\n",
    "hl_df.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Maturity</th>\n",
       "      <th>Series</th>\n",
       "      <th>prediction</th>\n",
       "      <th>residual</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>3 MO</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.00607123</td>\n",
       "      <td>0.0560712</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6 MO</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0515439</td>\n",
       "      <td>0.0284561</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>0.194281</td>\n",
       "      <td>-0.0742805</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>0.544726</td>\n",
       "      <td>-0.144726</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>0.924423</td>\n",
       "      <td>-0.144423</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>1.63469</td>\n",
       "      <td>0.0653145</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>2.20727</td>\n",
       "      <td>0.17273</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>10 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>2.81755</td>\n",
       "      <td>0.162453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>20 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>3.72293</td>\n",
       "      <td>-0.0629295</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>30 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>4.04522</td>\n",
       "      <td>-0.14522</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Maturity Series  prediction   residual\n",
       "0     3 MO      1 -0.00607123  0.0560712\n",
       "1     6 MO      1   0.0515439  0.0284561\n",
       "2     1 YR      1    0.194281 -0.0742805\n",
       "3     2 YR      1    0.544726  -0.144726\n",
       "4     3 YR      1    0.924423  -0.144423\n",
       "5     5 YR      1     1.63469  0.0653145\n",
       "6     7 YR      1     2.20727    0.17273\n",
       "7    10 YR      1     2.81755   0.162453\n",
       "8    20 YR      1     3.72293 -0.0629295\n",
       "9    30 YR      1     4.04522   -0.14522"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results_5d = pd.concat(results_5d)\n",
    "results_10d = pd.concat(results_10d)\n",
    "results_1M = pd.concat(results_1M)\n",
    "results_5d.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Convert the predicted results to a statistic summary\n",
    "def df_convert(df):\n",
    "    means = []\n",
    "    stds = []\n",
    "    RMSEs = []\n",
    "    maturity = df[\"Maturity\"].values[:len(term)]\n",
    "    for i in maturity:\n",
    "        grouped = df.groupby(\"Maturity\")\n",
    "        grouped_i = grouped.get_group(i)\n",
    "        mean = np.mean(grouped_i[\"prediction\"])\n",
    "        std = np.std(grouped_i[\"prediction\"])\n",
    "        RMSE = np.sqrt(np.mean(np.power(grouped_i[\"residual\"],2)))\n",
    "        means.append(mean)\n",
    "        stds.append(std)\n",
    "        RMSEs.append(RMSE)\n",
    "    result = pd.DataFrame({\"Mean\":means,\"Std\":stds,\"RMSE\":RMSEs},index=maturity)\n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Mean_5d</th>\n",
       "      <th>RMSE_5d</th>\n",
       "      <th>Std_5d</th>\n",
       "      <th>Mean_10d</th>\n",
       "      <th>RMSE_10d</th>\n",
       "      <th>Std_10d</th>\n",
       "      <th>Mean_1M</th>\n",
       "      <th>RMSE_1M</th>\n",
       "      <th>Std_1M</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3 MO</th>\n",
       "      <td>-0.047015</td>\n",
       "      <td>0.098288</td>\n",
       "      <td>0.047202</td>\n",
       "      <td>-0.041555</td>\n",
       "      <td>0.094988</td>\n",
       "      <td>0.053845</td>\n",
       "      <td>-0.034394</td>\n",
       "      <td>0.088234</td>\n",
       "      <td>0.057673</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6 MO</th>\n",
       "      <td>0.027894</td>\n",
       "      <td>0.045577</td>\n",
       "      <td>0.025987</td>\n",
       "      <td>0.030217</td>\n",
       "      <td>0.043029</td>\n",
       "      <td>0.031378</td>\n",
       "      <td>0.032732</td>\n",
       "      <td>0.039158</td>\n",
       "      <td>0.034382</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1 YR</th>\n",
       "      <td>0.195569</td>\n",
       "      <td>0.080534</td>\n",
       "      <td>0.012401</td>\n",
       "      <td>0.192716</td>\n",
       "      <td>0.081237</td>\n",
       "      <td>0.014262</td>\n",
       "      <td>0.187640</td>\n",
       "      <td>0.083000</td>\n",
       "      <td>0.018875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2 YR</th>\n",
       "      <td>0.567950</td>\n",
       "      <td>0.160405</td>\n",
       "      <td>0.042714</td>\n",
       "      <td>0.558090</td>\n",
       "      <td>0.158277</td>\n",
       "      <td>0.046749</td>\n",
       "      <td>0.542970</td>\n",
       "      <td>0.153928</td>\n",
       "      <td>0.054782</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3 YR</th>\n",
       "      <td>0.946759</td>\n",
       "      <td>0.125014</td>\n",
       "      <td>0.049469</td>\n",
       "      <td>0.932882</td>\n",
       "      <td>0.119568</td>\n",
       "      <td>0.056847</td>\n",
       "      <td>0.912274</td>\n",
       "      <td>0.113781</td>\n",
       "      <td>0.068988</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5 YR</th>\n",
       "      <td>1.626309</td>\n",
       "      <td>0.101277</td>\n",
       "      <td>0.034195</td>\n",
       "      <td>1.609132</td>\n",
       "      <td>0.098187</td>\n",
       "      <td>0.043021</td>\n",
       "      <td>1.584612</td>\n",
       "      <td>0.113363</td>\n",
       "      <td>0.059803</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7 YR</th>\n",
       "      <td>2.159538</td>\n",
       "      <td>0.194752</td>\n",
       "      <td>0.037504</td>\n",
       "      <td>2.141817</td>\n",
       "      <td>0.180609</td>\n",
       "      <td>0.031031</td>\n",
       "      <td>2.117337</td>\n",
       "      <td>0.172590</td>\n",
       "      <td>0.038764</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10 YR</th>\n",
       "      <td>2.719648</td>\n",
       "      <td>0.165098</td>\n",
       "      <td>0.078086</td>\n",
       "      <td>2.702540</td>\n",
       "      <td>0.164543</td>\n",
       "      <td>0.058686</td>\n",
       "      <td>2.679901</td>\n",
       "      <td>0.152380</td>\n",
       "      <td>0.036683</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20 YR</th>\n",
       "      <td>3.542224</td>\n",
       "      <td>0.098838</td>\n",
       "      <td>0.159437</td>\n",
       "      <td>3.527240</td>\n",
       "      <td>0.147169</td>\n",
       "      <td>0.133223</td>\n",
       "      <td>3.509166</td>\n",
       "      <td>0.182105</td>\n",
       "      <td>0.096286</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30 YR</th>\n",
       "      <td>3.834177</td>\n",
       "      <td>0.126285</td>\n",
       "      <td>0.190173</td>\n",
       "      <td>3.820073</td>\n",
       "      <td>0.166075</td>\n",
       "      <td>0.162069</td>\n",
       "      <td>3.803813</td>\n",
       "      <td>0.197906</td>\n",
       "      <td>0.122024</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        Mean_5d   RMSE_5d    Std_5d  Mean_10d  RMSE_10d   Std_10d   Mean_1M  \\\n",
       "3 MO  -0.047015  0.098288  0.047202 -0.041555  0.094988  0.053845 -0.034394   \n",
       "6 MO   0.027894  0.045577  0.025987  0.030217  0.043029  0.031378  0.032732   \n",
       "1 YR   0.195569  0.080534  0.012401  0.192716  0.081237  0.014262  0.187640   \n",
       "2 YR   0.567950  0.160405  0.042714  0.558090  0.158277  0.046749  0.542970   \n",
       "3 YR   0.946759  0.125014  0.049469  0.932882  0.119568  0.056847  0.912274   \n",
       "5 YR   1.626309  0.101277  0.034195  1.609132  0.098187  0.043021  1.584612   \n",
       "7 YR   2.159538  0.194752  0.037504  2.141817  0.180609  0.031031  2.117337   \n",
       "10 YR  2.719648  0.165098  0.078086  2.702540  0.164543  0.058686  2.679901   \n",
       "20 YR  3.542224  0.098838  0.159437  3.527240  0.147169  0.133223  3.509166   \n",
       "30 YR  3.834177  0.126285  0.190173  3.820073  0.166075  0.162069  3.803813   \n",
       "\n",
       "        RMSE_1M    Std_1M  \n",
       "3 MO   0.088234  0.057673  \n",
       "6 MO   0.039158  0.034382  \n",
       "1 YR   0.083000  0.018875  \n",
       "2 YR   0.153928  0.054782  \n",
       "3 YR   0.113781  0.068988  \n",
       "5 YR   0.113363  0.059803  \n",
       "7 YR   0.172590  0.038764  \n",
       "10 YR  0.152380  0.036683  \n",
       "20 YR  0.182105  0.096286  \n",
       "30 YR  0.197906  0.122024  "
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_5d = df_convert(results_5d)\n",
    "final_10d = df_convert(results_10d)\n",
    "final_1M = df_convert(results_1M)\n",
    "finals_DNS = pd.concat([final_5d,final_10d,final_1M],axis=1)\n",
    "columns = ['Mean_5d', 'RMSE_5d', 'Std_5d','Mean_10d', 'RMSE_10d', 'Std_10d','Mean_1M', 'RMSE_1M', 'Std_1M']\n",
    "finals_DNS.columns = columns\n",
    "finals_DNS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 3 Use Ramdom walk to predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Maturity</th>\n",
       "      <th>Series</th>\n",
       "      <th>prediction</th>\n",
       "      <th>residual</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>3 MO</td>\n",
       "      <td>1</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6 MO</td>\n",
       "      <td>1</td>\n",
       "      <td>0.08</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>0.12</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>0.4</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>0.78</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>1.7</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>2.38</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>10 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>2.98</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>20 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>3.66</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>30 YR</td>\n",
       "      <td>1</td>\n",
       "      <td>3.9</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Maturity Series prediction residual\n",
       "0     3 MO      1       0.05        0\n",
       "1     6 MO      1       0.08        0\n",
       "2     1 YR      1       0.12        0\n",
       "3     2 YR      1        0.4        0\n",
       "4     3 YR      1       0.78        0\n",
       "5     5 YR      1        1.7        0\n",
       "6     7 YR      1       2.38        0\n",
       "7    10 YR      1       2.98        0\n",
       "8    20 YR      1       3.66        0\n",
       "9    30 YR      1        3.9        0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Random Walk Model\n",
    "results_5d_RW = []\n",
    "results_10d_RW = []\n",
    "results_1M_RW = []\n",
    "\n",
    "series_num = 1\n",
    "for index in index_best20:\n",
    "    # For each of date in best20, select data 6 month prior to that date as sample \n",
    "    # to fit AR models for betas\n",
    "    endDate_sample = index\n",
    "    predictions = []\n",
    "    \n",
    "    for length in length_predict:\n",
    "        date_lag = next_business_day(endDate_sample,length-1)\n",
    "        date_observation = next_business_day(endDate_sample,length)\n",
    "\n",
    "        CMT_hat = sample.loc[date_lag].values\n",
    "        CMT = sample.loc[date_observation].values\n",
    "        \n",
    "        residuals = CMT - CMT_hat\n",
    "\n",
    "        series = np.array([series_num]*len(CMT))\n",
    "        \n",
    "        data = np.hstack([maturity.reshape(-1,1),series.reshape(-1,1),CMT_hat.reshape(-1,1),residuals.reshape(-1,1)])\n",
    "\n",
    "        df_predict = pd.DataFrame(data,columns=[\"Maturity\",\"Series\",\"prediction\",\"residual\"])\n",
    "\n",
    "        predictions.append(df_predict)\n",
    "    \n",
    "    results_5d_RW.append(predictions[0])\n",
    "    results_10d_RW.append(predictions[1])\n",
    "    results_1M_RW.append(predictions[2])\n",
    "    \n",
    "    series_num += 1\n",
    "    \n",
    "results_5d_RW = pd.concat(results_5d_RW)\n",
    "results_10d_RW = pd.concat(results_10d_RW)\n",
    "results_1M_RW = pd.concat(results_1M_RW)    \n",
    "results_5d_RW.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Mean_5d_RW</th>\n",
       "      <th>RMSE_5d_RW</th>\n",
       "      <th>Std_5d_RW</th>\n",
       "      <th>Mean_10d_RW</th>\n",
       "      <th>RMSE_10d_RW</th>\n",
       "      <th>Std_10d</th>\n",
       "      <th>Mean_1M_RW</th>\n",
       "      <th>RMSE_1M_RW</th>\n",
       "      <th>Std_1M_RW</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3 MO</th>\n",
       "      <td>0.0470</td>\n",
       "      <td>0.008367</td>\n",
       "      <td>0.018735</td>\n",
       "      <td>0.0430</td>\n",
       "      <td>0.005000</td>\n",
       "      <td>0.015843</td>\n",
       "      <td>0.0365</td>\n",
       "      <td>0.003873</td>\n",
       "      <td>0.007263</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6 MO</th>\n",
       "      <td>0.0720</td>\n",
       "      <td>0.005916</td>\n",
       "      <td>0.020396</td>\n",
       "      <td>0.0670</td>\n",
       "      <td>0.005477</td>\n",
       "      <td>0.017349</td>\n",
       "      <td>0.0615</td>\n",
       "      <td>0.007071</td>\n",
       "      <td>0.010137</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1 YR</th>\n",
       "      <td>0.1180</td>\n",
       "      <td>0.006325</td>\n",
       "      <td>0.012884</td>\n",
       "      <td>0.1155</td>\n",
       "      <td>0.006325</td>\n",
       "      <td>0.012031</td>\n",
       "      <td>0.1090</td>\n",
       "      <td>0.007416</td>\n",
       "      <td>0.013000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2 YR</th>\n",
       "      <td>0.4075</td>\n",
       "      <td>0.015000</td>\n",
       "      <td>0.020946</td>\n",
       "      <td>0.4075</td>\n",
       "      <td>0.013038</td>\n",
       "      <td>0.019203</td>\n",
       "      <td>0.4020</td>\n",
       "      <td>0.018574</td>\n",
       "      <td>0.022494</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3 YR</th>\n",
       "      <td>0.8265</td>\n",
       "      <td>0.023238</td>\n",
       "      <td>0.059856</td>\n",
       "      <td>0.8230</td>\n",
       "      <td>0.024799</td>\n",
       "      <td>0.057541</td>\n",
       "      <td>0.8220</td>\n",
       "      <td>0.029411</td>\n",
       "      <td>0.053254</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5 YR</th>\n",
       "      <td>1.7060</td>\n",
       "      <td>0.030249</td>\n",
       "      <td>0.036797</td>\n",
       "      <td>1.6835</td>\n",
       "      <td>0.027749</td>\n",
       "      <td>0.045747</td>\n",
       "      <td>1.6570</td>\n",
       "      <td>0.037550</td>\n",
       "      <td>0.054690</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7 YR</th>\n",
       "      <td>2.3400</td>\n",
       "      <td>0.032016</td>\n",
       "      <td>0.070143</td>\n",
       "      <td>2.3040</td>\n",
       "      <td>0.030984</td>\n",
       "      <td>0.088736</td>\n",
       "      <td>2.2560</td>\n",
       "      <td>0.038987</td>\n",
       "      <td>0.083331</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10 YR</th>\n",
       "      <td>2.8575</td>\n",
       "      <td>0.028636</td>\n",
       "      <td>0.144183</td>\n",
       "      <td>2.8235</td>\n",
       "      <td>0.027386</td>\n",
       "      <td>0.158470</td>\n",
       "      <td>2.7710</td>\n",
       "      <td>0.033912</td>\n",
       "      <td>0.133563</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20 YR</th>\n",
       "      <td>3.4770</td>\n",
       "      <td>0.030000</td>\n",
       "      <td>0.210002</td>\n",
       "      <td>3.4390</td>\n",
       "      <td>0.030984</td>\n",
       "      <td>0.223515</td>\n",
       "      <td>3.3850</td>\n",
       "      <td>0.033015</td>\n",
       "      <td>0.184377</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30 YR</th>\n",
       "      <td>3.7215</td>\n",
       "      <td>0.028196</td>\n",
       "      <td>0.207949</td>\n",
       "      <td>3.6870</td>\n",
       "      <td>0.029917</td>\n",
       "      <td>0.218589</td>\n",
       "      <td>3.6400</td>\n",
       "      <td>0.030414</td>\n",
       "      <td>0.170822</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Mean_5d_RW  RMSE_5d_RW  Std_5d_RW  Mean_10d_RW  RMSE_10d_RW   Std_10d  \\\n",
       "3 MO       0.0470    0.008367   0.018735       0.0430     0.005000  0.015843   \n",
       "6 MO       0.0720    0.005916   0.020396       0.0670     0.005477  0.017349   \n",
       "1 YR       0.1180    0.006325   0.012884       0.1155     0.006325  0.012031   \n",
       "2 YR       0.4075    0.015000   0.020946       0.4075     0.013038  0.019203   \n",
       "3 YR       0.8265    0.023238   0.059856       0.8230     0.024799  0.057541   \n",
       "5 YR       1.7060    0.030249   0.036797       1.6835     0.027749  0.045747   \n",
       "7 YR       2.3400    0.032016   0.070143       2.3040     0.030984  0.088736   \n",
       "10 YR      2.8575    0.028636   0.144183       2.8235     0.027386  0.158470   \n",
       "20 YR      3.4770    0.030000   0.210002       3.4390     0.030984  0.223515   \n",
       "30 YR      3.7215    0.028196   0.207949       3.6870     0.029917  0.218589   \n",
       "\n",
       "       Mean_1M_RW  RMSE_1M_RW  Std_1M_RW  \n",
       "3 MO       0.0365    0.003873   0.007263  \n",
       "6 MO       0.0615    0.007071   0.010137  \n",
       "1 YR       0.1090    0.007416   0.013000  \n",
       "2 YR       0.4020    0.018574   0.022494  \n",
       "3 YR       0.8220    0.029411   0.053254  \n",
       "5 YR       1.6570    0.037550   0.054690  \n",
       "7 YR       2.2560    0.038987   0.083331  \n",
       "10 YR      2.7710    0.033912   0.133563  \n",
       "20 YR      3.3850    0.033015   0.184377  \n",
       "30 YR      3.6400    0.030414   0.170822  "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_5d_RW = df_convert(results_5d_RW)\n",
    "final_10d_RW = df_convert(results_10d_RW)\n",
    "final_1M_RW = df_convert(results_1M_RW)\n",
    "finals_RW = pd.concat([final_5d_RW,final_10d_RW,final_1M_RW],axis=1)\n",
    "columns = ['Mean_5d_RW', 'RMSE_5d_RW', 'Std_5d_RW','Mean_10d_RW', 'RMSE_10d_RW', 'Std_10d','Mean_1M_RW', 'RMSE_1M_RW', 'Std_1M_RW']\n",
    "finals_RW.columns = columns\n",
    "finals_RW"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DNS v.s Random Walk\n",
    "Since its corresponding RMSEs are larger, the DNS model performs no better than random walk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
